package com.honey.compilation.sql.ddl;

import com.honey.compilation.sql.SqlCommand;
import com.honey.compilation.sql.SqlKeyWord;
import com.honey.compilation.sql.SqlScript;
import com.honey.compilation.sql.ddl.SetTransactionAccessMode.AccessMode;
import com.honey.compilation.sql.ddl.SetTransactionLevel.IsolationLevel;
import com.honey.core.builder.CharacterBuilder;
import com.honey.core.builder.CharacterBuilderFactory;
import com.honey.core.compiler.CompilationException;
import com.honey.core.compiler.IndentSpace;

/**
 * 在sql 92中没有定义如何开始事务,在SQL 99中定义了事务开始语法,语法格式如下 :
 * 
 * &lt;start transaction statement&gt;    
 * ::=  START TRANSACTION &lt;transaction mode&gt; [ { &lt;comma&gt; &lt;transaction mode&gt; }...]<br />
 * &lt;transaction mode&gt;    ::=   &lt;isolation level&gt; | &lt;transaction access mode&gt; <br />
 * &lt;isolation level&gt;    ::=   ISOLATION LEVEL &lt;level of isolation&gt;<br />
 * &lt;level of isolation&gt;    ::= <br />
 * READ UNCOMMITTED <br />
 * |     READ COMMITTED <br />
 * |     REPEATABLE READ <br />
 * |     SERIALIZABLE<br />
 * &lt;transaction access mode&gt;    ::=   READ ONLY | READ WRITE
 * 
 * 在语法中定义事务隔离级别和事务的读取模式(和SQL 92中的定义一致)
 * @author Administrator
 *
 */
public class StartTransaction  extends SQL92Comment implements SqlCommand , SqlScript{
	
	private IsolationLevel isolationLevel ;
	
	private AccessMode accessMode ;
	
	/**
	 * 设定数据库默认事务级别
	 */
	public void setDefaultLevel(){
		isolationLevel = null;
	}
	
	/**
	 * 未授权读取:允许脏读取，但不允许更新丢失。
	 */
	public void setReadUncommittedLevel(){
		this.isolationLevel = IsolationLevel.READ_UNCOMMITTED;
	}
	
	/**
	 * 授权读取:允许不可重复读取，但不允许脏读取
	 */
	public void setReadCommittedLevel(){
		this.isolationLevel = IsolationLevel.READ_COMMITTED;
	}
	
	
	/**
	 * 可重复读取 : 禁止不可重复读取和脏读取，但是有时可能出现幻影数据
	 */
	public void setRepeatableReadLevel(){
		this.isolationLevel = IsolationLevel.REPEATABLE_READ;
	}
	
	
	/**
	 * 序列化 : 提供严格的事务隔离。
	 */
	public void setSerializableLevel(){
		this.isolationLevel = IsolationLevel.SERIALIZABLE;
	}
	
	/**
	 * 只读事务
	 */
	public void setReadonly(){
		this.accessMode = accessMode.READ_ONLY;
	} 
	
	/**
	 * 可写事务
	 */
	public void setReadwrite (){
		this.accessMode = accessMode.READ_WRITE;
	} 
	
	
	@Override
	public String getCommand() {
		
		return "START TRANSACTION";
	}
	
	@Override
	public CharacterBuilder compiledContent(int indentLevel ) throws CompilationException {
		CharacterBuilder answer = CharacterBuilderFactory.createC16StringBuilder();
		answer.append(super.compiledContent(indentLevel));
		IndentSpace.spaceIndent(answer, indentLevel);
		answer.append("START TRANSACTION "); 
		if(isolationLevel != null){
			answer.append(SqlKeyWord.ISOLATION )
			.append(SqlKeyWord.LEVEL)
			.append(isolationLevel)
			;
		}
		
		if( accessMode != null){
			if(isolationLevel != null){
				answer.append(SqlKeyWord.OPERATION_COMMA );
			}
			answer.append(accessMode);
		}
		
		answer.append(SqlKeyWord.OPERATION_SEMICOLON );
		return answer ;
	}
}
